package imvu.rbox.object
{
	import flash.display.DisplayObject;
	import flash.display.DisplayObjectContainer;
	import flash.display.MovieClip;
	import flash.display.Sprite;
	import flash.events.TimerEvent;
	import flash.geom.Point;
	import flash.utils.ByteArray;
	import flash.utils.Timer;
	
	import imvu.rbox.event.ActionEvent;
	import imvu.rbox.event.BoxEvent;
	import imvu.rbox.global.GStatic;
	import imvu.rbox.struct.BoxInfo;

	public class MainGamePlay extends Sprite
	{		
		private static const MAX_WIDTH:Number	= 10;	//	地图上限宽度
		private static const MAX_HEIGHT:Number	= 20;	//	地图上限高度
		private static const MAX_LEVEL:Number	= 19;	//	每次移动检测泊毫秒数上限
		private static const MOVE_SPEED:Number	= 85;	//	每级减少的毫秒数
		
		private static const CAN_MOVE:Number		= 0;	//	可以移动
		private static const NO_LEFT_MOVE:Number	= 1;	//	不允许左移
		private static const NO_RIGHT_MOVE:Number	= 2;	//	不允许右移
		private static const NO_DOWN_MOVE:Number	= 3;	//	不允许下移
		private static const HIT_BOX:Number			= 4;	//	与其它方块碰撞
		
		public var mcPlace:Sprite;			//	方块刷新的初始位置
		public var mcHotMovie:MovieClip;	//	触发进度条影片对象
		public var mcGameOverFlag:Sprite;	//	游戏结束标识
		public var mcBomb:MovieClip;		//	爆发动画
		
		private var baseArray:Array;		//	当前游戏数组
		private var boxArray:Array;			//	方块数组		
		private var newArray:Array;			//	与方块结合后的数组
		
		private var boxPoint:Point;			//	方块对象的初始位置
		private var boxInfo:BoxInfo;		//	方块对象的数据值
		
		private var objArray:Array;			//	对象列表		
		 
		private var gTime:Timer;			//	全局计时对象
		private var nowWaitTime:Number;		//	当前计数器对象
		private var isCanAction:Boolean;	//	是否可以使用操作键
		
		public function MainGamePlay()
		{
			InitObject();
			
			isCanAction = false;
			isGameOver = false;			
		}
		
		public function InitGameBase():void
		{
			InitObject(true);
		}
		
		public function set hotPercent(num:Number):void
		{
			num = (num <= 1) ? 1 : (num >= 100) ? 100 : num;
			
			mcHotMovie.gotoAndStop(Math.floor(num));
		}
		
		public function set isGameOver(flag:Boolean):void
		{
			mcGameOverFlag.visible = flag;
			if(gTime)
			{
				gTime.stop();
			}			
		}
		
		public function get isGameOver():Boolean
		{
			return mcGameOverFlag.visible;
		}
		
		public function set isBomb(flag:Boolean):void
		{
			if(flag)
			{
				this.mcBomb.gotoAndPlay(2);
			}
		}
		
		//	删除侦听
		public function DeleteListener():void
		{
			this.gTime.stop();
		}
		
		//	向底部添加一行
		public function UpdataBgdata(array:Array, isChangeTime:Boolean = false):void
		{
			//**
			this.baseArray.shift();
			this.baseArray.push(array);
			
			if(isChangeTime)
			{
				this.nowWaitTime = 0;
				this.boxPoint.y --;
				
				if(this.boxPoint.y < -1)
				{
					this.boxPoint.y = -1;
				}				
			}
			
			CheckGameData();
			/**
			ChangeGameData();
			
			var obj:Object = new Object();			
			obj.data = gameData;
			
			this.dispatchEvent(new ActionEvent(ActionEvent.UPDATA_LINE, obj));
			//**/
		}

		//	刷新游戏底部数据
		public function RushBgData(array:Array):void
		{
			// trace("更新背景数组: " + array);
			if(array.length > 0)
			{
				this.baseArray = array;
			
				//CheckGameData();
				ChangeGameData();
			}
		}
		
		//	更新方块的位置（要注意三个方向的碰撞检测）
		public function ChangePlace(arrow:Number):void
		{
			if(isCanAction)
			{
				isCanAction = false;
				switch(arrow)
				{
					case BoxEvent.LEFT_MOVE :
						if(CheckCanMove(this.boxPoint.x - 1, this.boxPoint.y) == CAN_MOVE)
						{
							// trace("左移一格");
							this.boxPoint.x --;							
							ChangeGameData();
						}
						else
						{
							trace("不能左移了");
						}
						// isCanAction = true;
						break;
					
					case BoxEvent.RIGHT_MOVE :
						if(CheckCanMove(this.boxPoint.x + 1, this.boxPoint.y) == CAN_MOVE)
						{
							// trace("右移一格");
							this.boxPoint.x ++;
							isCanAction = true;
							ChangeGameData();
						}
						else
						{
							trace("不能右移了");
						}
						// isCanAction = true;
						break;
					
					case BoxEvent.DOWN_MOVE :
						if(this.boxInfo.id == BoxEvent.BOX_FLY)
						{
							CleanOneBox();
						}
						else
						{
							if(CheckCanMove(this.boxPoint.x, this.boxPoint.y + 1) == CAN_MOVE)
							{
								this.boxPoint.y ++;
								isCanAction = true;
								ChangeGameData();
							}
							else
							{
								trace("不能下移了");
								CheckGameData();
							}
						}						
						break;
					
					case BoxEvent.FAST_DOWN :
						//**
						if(this.boxInfo.id == BoxEvent.BOX_FLY)
						{
							CleanOneBox();
						}
						else
						{
							for(var i:int = this.boxPoint.y; i < MAX_HEIGHT; i++)
							{
								// trace("now I:" + i);
								if(!Boolean(CheckCanMove(this.boxPoint.x, i) == CAN_MOVE))
								{
									// trace("done!");
									this.boxPoint.y = i - 1;
									ChangeGameData();
									CheckGameData();
									break;
								}
							} //**/
						}
						break;
				}
				isCanAction = true;
			}
		}
		
		//	更新方块的形状
		public function ChangeShape():void
		{
			if(isCanAction)
			{
				if(this.boxInfo)
				{
					if(this.boxInfo.id == BoxEvent.BOX_FLY)
					{
						CleanOneBox();
					}
					else
					{
						// trace("未改变前状态::" + this.boxInfo.boxData.statue);
						var oldArrow:Number = this.boxInfo.arrow;
						
						if(oldArrow >= 0)
						{
							this.boxInfo.arrow ++;
							this.boxArray = this.boxInfo.toArray();
							
							var cFlag:Number = CheckCanMove(this.boxPoint.x, this.boxPoint.y);
							
							// trace("当前检测结果::" + this.boxInfo.arrow + " : " + cFlag);
							// trace("当前P:" + this.boxPoint.x, this.boxPoint.y);
							
							if(cFlag == CAN_MOVE)
							{
								// trace("确认改变形状");
								this.boxArray = this.boxInfo.toArray();						
							}
							else
							{
								// trace("取消改变形状");
								if(CheckCanMove(this.boxPoint.x-1, this.boxPoint.y) == CAN_MOVE)
								{
									this.boxPoint.x --;								
								}
								else if(CheckCanMove(this.boxPoint.x+1, this.boxPoint.y) == CAN_MOVE)
								{
									this.boxPoint.x ++;
								}
								else
								{
									this.boxInfo.arrow = oldArrow;
									this.boxArray = this.boxInfo.toArray();
								}						
							}
							ChangeGameData();
						}		
					}			
					// trace("改变后状态::" + this.boxInfo.boxData.statue);
				}
			}
		}
		
		private function CleanOneBox():void
		{
			for(var i:int = this.baseArray.length - 1; i >= this.boxPoint.y; i--)
			{
				if(this.baseArray[i][this.boxPoint.x] == 0)
				{
					this.baseArray[i][this.boxPoint.x] = 1;
					break;
				}
			}
			CheckCleanOneLine();
		}
		
		//	返回一维数组的游戏数据
		public function get gameData():Array
		{
			var tArray:Array = new Array();
			 
			for(var i:int = 0; i < 20; i++)
			{
				for(var j:int = 0; j < 10; j++)
				{
					tArray.push(newArray[i][j]);
				}
			}
			return tArray;
		}
		
		public function get ___gameData():ByteArray
		{
			var tArray:ByteArray = new ByteArray();
			for(var i:int = 0; i < 20; i++)
			{
				for(var j:int = 0; j < 10; j++)
				{
					tArray.writeByte(newArray[i][j]);
				}
			}
			return tArray;
			
		}
		
		public function set boxObject(bInfo:BoxInfo):void
		{
			//trace("GetGameDATA::" + bInfo);
			//trace("baseArray::\n" + this.baseArray.join("\n"));
			//trace(this.boxInfo.boxData.statue);

			this.boxInfo = bInfo;
			this.boxPoint = new Point(4, -1);
			
			if(this.boxInfo)
			{
				this.boxArray = this.boxInfo.toArray();				
				
				// trace("当前方块数组：" + this.boxArray.join("\n"));
				
				isCanAction = true;
				
				nowWaitTime = Number(MAX_LEVEL - GStatic.myInfo.gameSpeed) - 2;
				
				if(!gTime)
				{
					gTime = new Timer(MOVE_SPEED);
					gTime.addEventListener(TimerEvent.TIMER, onGameListener);
				}

				gTime.start();
	
				ChangeGameData();
			}
			CheckGameData();
		}
		
		//---------------------------------------------------------------
		
		private function InitObject(isRush:Boolean = false):void
		{
			baseArray = GetInitData(MAX_WIDTH, MAX_HEIGHT);
			boxArray = GetInitData(4, 4);
			newArray = GetInitData(MAX_WIDTH, MAX_HEIGHT);
		
			this.hotPercent = 0;
			this.boxObject = null;
			this.isGameOver = false;
			
			for(var i:int = 0; i < this.numChildren; i++)
			{
				var disp:DisplayObject = this.getChildAt(i);
				if(disp is DisplayObjectContainer)
				{
					DisplayObjectContainer(disp).mouseChildren = DisplayObjectContainer(disp).mouseChildren = false;
				}
			}
				
			RushData();
		}		
		
		//------------------------------------------------------------
		
		//	取得初始化数组
		private function GetInitData(ww:Number, hh:Number):Array
		{
			var tArray:Array = new Array();
			for(var i:int = 0; i < hh; i++)
			{
				tArray[i] = new Array();
				for(var j:int = 0; j < ww; j++)
				{
					tArray[i][j] = 0;
				}
			}
			
			return tArray;
		}
		
		//	刷新屏幕上的显示
		private function RushData():void
		{
			//trace("RushData::");
			//trace("baseArray::" + this.baseArray);
			//trace("newArray::" + this.newArray);
			
			try
			{
			//	如果已经存在对象,则进行相应的更新,否则,重新创建新的对象
			if(!objArray)
			{
				objArray = new Array();
			}
			
			//	为方块赋值
			for(var i:int = 0; i < newArray.length; i++)
			{
				if(!objArray[i])
				{
					objArray[i] = new Array();
				}
				for(var j:int = 0; j < newArray[i].length; j++)
				{
					var box:BoxMovie;
					if(objArray[i][j])
					{
						box = objArray[i][j];
					}
					else
					{
						box = new BoxMovie();
						box.x = j * box.width;
						box.y = i * box.height;
						mcPlace.addChild(box);
						
						objArray[i][j] = box;
					}
					box.id = newArray[i][j];
				}
			}
			}
			catch(err:*)
			{
				trace("第三个位置发生错误",err);
			}
			
			//	为空白方块赋黄色提示
			//**
			try
			{
				for(var m:int = 0; m < 4; m++)
				{
					if(this.boxArray[0][m] > 0 || this.boxArray[1][m] > 0 || this.boxArray[2][m] > 0 || this.boxArray[3][m] > 0)
					{
						var nx:Number = this.boxPoint.x + m;
						
						if(nx >= 0)
						{
							for(var n:int = 0; n < this.objArray.length; n++)
							{
								if(this.objArray[n][nx].id == 0)
								{
									if(n >= this.boxPoint.y)
									{
										BoxMovie(this.objArray[n][nx]).isFire = GStatic.isShowInfo;
									}
								}
							}
						}
					}
				}//**/
			}
			catch(err:*)
			{
				trace("显示高亮方块出错:" + err);
			}
		}
		
		private function ChangeGameData():void
		{
			var i:int, j:int;
		
			//trace("DoCheckGameData:");			
			//trace("base new Array:: \n" + this.newArray);
			//trace("baseArray::" + this.baseArray);
			//trace("newArray::" + this.newArray);
			
			this.newArray = GetInitData(MAX_WIDTH, MAX_HEIGHT);
			
			try
			{
				for(i = 0; i < this.baseArray.length; i++)
				{
					this.newArray[i] = this.baseArray[i].slice();
				}
			}
			catch(err:*)
			{
				trace("第1个位置发生错误", err);
			}
			
			if(this.boxArray)
			{
				try
				{
				for(i = 0; i < 4; i++)
				{
					for(j = 0; j < 4; j++)
					{
						var px:Number = this.boxPoint.y + i;
						var py:Number = this.boxPoint.x + j;
						
						if(px >= 0 && px < MAX_HEIGHT && py >= 0 && py < MAX_WIDTH)
						{
							if(this.boxArray[i][j] > 0)
							{
								this.newArray[px][py] = this.boxArray[i][j];								
							}
						}			
					}
				}
				}
				catch(err:*)
				{
					trace("第2个位置发生错误",err);
				}
			}
			
			//trace("baseArray:\n" + this.boxArray);
			//trace("nnewArray:\n" + this.newArray);
			
			RushData();
		}
		
		//----------------------------------------------------------
		
		private function onGameListener(e:TimerEvent):void
		{
			if(this.boxInfo)
			{
				nowWaitTime ++;
				
				// trace(this.nowWaitTime, GStatic.myInfo.gameSpeed);
				var waitNum:Number = Number(MAX_LEVEL - GStatic.myInfo.gameSpeed);
				// trace("nowWaitNum::" + waitNum);
				
				if(nowWaitTime >= waitNum)
				{
					nowWaitTime = 0;
					
					CheckGameData();
				}
			}
		}
		
		private function CheckGameData():void
		{
			var obj:Object;
			
			if(this.boxInfo)
			{
				this.boxPoint.y ++;
				var moveFlag:Number = this.CheckCanMove(this.boxPoint.x, this.boxPoint.y)
				if(moveFlag == CAN_MOVE)
				{
					// trace("改变对象位置", this.boxPoint.x, this.boxPoint.y);
					ChangeGameData();
					
					//**
					obj = new Object();
					obj.lines = 0;	
					obj.data = gameData;
					
					// trace("更新游戏数据");
					this.dispatchEvent(new ActionEvent(ActionEvent.UPDATA_LINE, obj));
					//**/
				}
				else
				{
					this.gTime.stop();	
					this.isCanAction = false;
					
					//trace("baseArray::" + this.baseArray);
					//trace("newArray::" + this.newArray);	
					
					if(this.boxInfo.id == BoxEvent.BOX_FLY)
					{
						this.boxArray = new BoxInfo().toArray();
						ChangeGameData();
					}	
					
					obj = new Object();
					obj.lines = CheckCleanLine();
					obj.data = gameData;		
					
					this.baseArray = this.newArray.slice();			
					
					//trace("nowSendData::" + obj.data);

					if(this.boxPoint.y <= 0)
					{
						trace("游戏结束");
						this.isGameOver = true;
						this.dispatchEvent(new ActionEvent(ActionEvent.GAME_DONE, obj));
					}
					else
					{
						trace("方块已经到底，不可再移动");						
						this.dispatchEvent(new ActionEvent(ActionEvent.BOX_DONE, obj));
					}
				}
			}
		}	
		
		private function CheckCleanOneLine():void
		{
			var moveFlag:Number = this.CheckCanMove(this.boxPoint.x, this.boxPoint.y)
			if(moveFlag == CAN_MOVE)
			{
				// trace("改变对象位置", this.boxPoint.x, this.boxPoint.y);				
				var obj:Object = new Object();
				obj.lines = CheckBaseLine();	
				obj.data = gameData;

				ChangeGameData();
				
				if(obj.lines > 0)
				{
					this.dispatchEvent(new ActionEvent(ActionEvent.UPDATA_LINE, obj));
				}
			}
			else
			{
				CheckGameData();
			}
		}
		
		private function CheckCleanLine():Number
		{
			var lines:Number = 0;
			
			for(var i:int = 0; i < this.newArray.length; i++)
			{
				var id:Number = 0;
				var tArray:Array = this.newArray[i];
				
				for(var j:int = 0; j < tArray.length; j++)
				{
					if(tArray[j] > 0)
					{
						id++;
					}
				}
				if(id == tArray.length)
				{
					lines ++;
					for(var k:int = i; k > 0; k--)
					{
						this.newArray[k] = this.newArray[k-1].slice();
					}
					for(var m:int = 0; m < this.newArray[0].length; m++)
					{
						this.newArray[0][m] = 0;
					}
				}
			}
			
			trace("清除了" + lines + " 行");
			return lines;
		}	 

		private function CheckBaseLine():Number
		{
			var lines:Number = 0;
			
			for(var i:int = 0; i < this.baseArray.length; i++)
			{
				var id:Number = 0;
				var tArray:Array = this.baseArray[i];
				
				for(var j:int = 0; j < tArray.length; j++)
				{
					if(tArray[j] > 0)
					{
						id++;
					}
				}
				if(id == tArray.length)
				{
					lines ++;
					for(var k:int = i; k > 0; k--)
					{
						this.baseArray[k] = this.baseArray[k-1].slice();
					}
					for(var m:int = 0; m < this.baseArray[0].length; m++)
					{
						this.baseArray[0][m] = 0;
					}
				}
			}
			
			trace("清除了" + lines + " 行");
			return lines;
		}	 
		
		private function CheckCanMove(xx:Number, yy:Number):Number
		{
			// trace("传入的值是:", xx, yy);
			// trace("当前boxArray::\n" + this.boxArray.join("\n"));
			for(var i:int = 0; i < 4; i++)
			{
				for(var j:int = 0; j < 4; j++)
				{
					var py:Number = yy + i;
					var px:Number = xx + j;
					
					// trace("px:",px,"  py:",py,"boxArray["+ i + "][" + j + "]=" + this.boxArray[i][j]);
					
					if(this.boxArray[i][j] > 0)
					{
						if(px < 0)
						{
							// trace("不能左移");
							return NO_LEFT_MOVE;
						}
						else if(px >= MAX_WIDTH)
						{
							// trace("不能右移");
							return NO_RIGHT_MOVE;
						}
						else if(py >= MAX_HEIGHT)
						{
							// trace("不能下移");
							return NO_DOWN_MOVE;
						} 
						else if(py >= 0)
						{
							if(this.baseArray[py][px] > 0)
							{
								// trace("碰到方块了");
								return HIT_BOX;		
							}
						}
					}			
				}
			}
			
			return CAN_MOVE;
		}
		
		//	检测对象是否还允许移动
		//	返回值:	0	允许移动
		//			1	不允许左移
		//			2 	不允许右移
		//			3	不允许下移
		//			4	碰到其它方块
		private function __CheckCanMove(xx:Number, yy:Number):Number
		{
			var tArray:Array = this.boxInfo.boxData.statue;
			
			// trace(tArray);
			// trace("nowBaseArray::" + this.baseArray.join("\n"));
			
			for(var i:int = 0; i < tArray.length; i++)
			{
				var p:Point = tArray[i];
				var px:Number = p.x + xx;
				var py:Number = p.y + yy;
				
				// trace("px:",px,"py:",py, "p:",p,"xx:",xx,"yy:",yy);
				
				if(px < 0)
				{
					// trace("不能左移");
					return NO_LEFT_MOVE;
				} 
				else if(px >= MAX_WIDTH)
				{
					// trace("不能右移");
					return NO_RIGHT_MOVE;
				} 
				else if(py >= MAX_HEIGHT)
				{
					//	单纯从位置改变上进行判断
					// trace("不能下移");
					return NO_DOWN_MOVE;
				}
				else
				{
					// // trace("nowCheck::" + px, py);
					
					if(px >= 0 && px < MAX_WIDTH && py >= 0 && py < MAX_HEIGHT)
					{
						// // trace("Test::" + this.baseArray[py][px]);
						if(this.baseArray[py][px] > 0)
						{
							// trace("碰到方块了");
							return HIT_BOX;				
						}
					}
				}
			}
			
			return CAN_MOVE;
		}		
	}	
}